package org.genuflex.components
{
	/*
	 * GenuflexAutoComplete
	 *
	 * Provides some convenience functionality on top of what a ComboBox
	 * does out of the box.  This is intended to be used with a dataProvider
	 * that is an ArrayCollection of objects.  The goal of the ComboBox in this case
	 * is to allow the user to select an object from a list and to return
	 * a specific ID (usually the primary key)
	 *
	 * With that in mind, the GenuflexAutoComplete must be specified with the following attributes:
	 *  - dataProvider
	 *  - selectedItemSource: object containing the selected ID
	 *  - primaryKeyField: the name of the field on the object that will return the ID
	 *  - foreignKeyField (optional): if the id on the selectedItemSource object is referenced by 
	 *                     something other than the primaryKeyField, you may specify that here
	 * 
	 * GenuflexAutoComplete will then automatically select the correct item based on the selectedItemID and
	 * inversely set selectedItemID after a new item is selected
	 */
	import mx.controls.ComboBox;
	import mx.collections.ArrayCollection;
	import flash.events.Event;
	import mx.events.ListEvent;
	import mx.events.FlexEvent;
	import mx.core.EdgeMetrics;
	import org.genuflex.utils.GenuflexDataFunctions;
	import com.adobe.flex.extras.controls.AutoComplete;

	public class GenuflexAutoComplete extends AutoComplete
	{
		public function GenuflexAutoComplete() {	}
		
		public function set headerItemLabel (value : String) : void {
			this.prompt = value;
		}
		
		[Bindable]
		private var _selectedItemID : Object = null;
		public function get selectedItemID() : int {
			//Return the id of the currently selected item
			if (selectedItem != null && primaryKeyField != null && selectedItem.hasOwnProperty(primaryKeyField)) {
				_selectedItemID = selectedItem[primaryKeyField];
			}
			else {
				_selectedItemID = null;
			}
			
			if (_selectedItemID == null || !(_selectedItemID is int)) {
				return 0;
			}
			else {
				return parseInt(_selectedItemID.toString());
			}
		}
		
		//When the selected item id is updated, try to select the current value by id
		public function set selectedItemIDValue(value : Object) : void {
			_selectedItemID = value;
			updateSelected();
		}

		//When the source is updated, try to select the current value by id
		private var _selectedItemSource : Object;
		public function set selectedItemSource( itemSource : Object) : void {
			_selectedItemSource = itemSource;
			if (_selectedItemSource != null && foreignKeyField != null && _selectedItemSource.hasOwnProperty(foreignKeyField)) {				
				selectedItemIDValue = _selectedItemSource[foreignKeyField];				
			}			
		}		
		
		//When the data provider is updated, try to select the current value
		public override function set dataProvider(object : Object) : void {
			super.dataProvider = object;
			updateSelected();
		}
		
		public var primaryKeyField : String;
		
		// If foreign key isn't set, it is assumed to be the same as the primaryKey
		private var _foreignKeyField : String;
		public function get foreignKeyField():String{
			if (GenuflexDataFunctions.isNotEmpty(_foreignKeyField)) {
				return _foreignKeyField;
			}
			else {
				return primaryKeyField;
			}
		}
		public function set foreignKeyField(value : String) : void {
			_foreignKeyField = value;
			
			if (_selectedItemSource != null && _foreignKeyField != null) {				
				selectedItemIDValue = _selectedItemSource[_foreignKeyField];				
			}			
		}
		
		public function updateSelected() : Boolean {
			var itemFound : Boolean = false;
			
			//If we have data (in ArrayCollection form), select the
			// proper item with the given id
			if (primaryKeyField != null && dataProvider != null && dataProvider is ArrayCollection) {
				for each(var item : Object in dataProvider) {
					//Look on this item for a property and compare it's value to the selectedItemID value
					if (item != null && item[primaryKeyField] == _selectedItemID) {
						this.selectedItem = item;
						itemFound = true;						
					}
				}
			}
			
			return itemFound;
		}
	}
}